package com.guigu.service_user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guigu.common_util.pojo.utils.JwtUtils;
import com.guigu.common_util.pojo.utils.MD5;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.guigu.common_util.pojo.utils.Result;
import com.guigu.service_user.entity.NewUser;
import com.guigu.service_user.entity.TbProvinces;
import com.guigu.service_user.entity.TbUser;
import com.guigu.service_user.entity.utlis.PageResult;
import com.guigu.service_user.entity.utlis.RandomUtil;
import com.guigu.service_user.mapper.TbUserMapper;
import com.guigu.service_user.service.ITbUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2020-07-09
 */
@Service
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser> implements ITbUserService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private AmqpTemplate amqpTemplate;   // rabbitmq

    @Autowired
    private TbUserMapper tbUserMapper;

    @Override
    public Result findPage(Map<String, Object> searchMap, Integer page, Integer size) {
        QueryWrapper<TbUser> wrapper = createExample(searchMap);
        //创建page对象
        Page<TbUser> pageAlbum = new Page<>(page,size);
        baseMapper.selectPage(pageAlbum,wrapper);
        return Result.ok().data("row",pageAlbum.getRecords()).data("total",pageAlbum.getTotal());
    }

    @Override
    public Result sendMsm(String phone) {
        // 1. 从redis中获取验证码，如何获取到直接返回
        String code = (String) redisTemplate.opsForValue().get(phone);
        if (!StringUtils.isEmpty(code)){
            return Result.ok();
        }
        // 如果redis中获取不到，进行阿里云发送
        // 随机发送一个值
        code = RandomUtil.getSixBitRandom();
        System.out.println("短信验证码："+ code);
        // 保存到redis 里
        redisTemplate.boundValueOps("code_" + phone).set(code+"");
        redisTemplate.boundValueOps("code_" + phone).expire(5, TimeUnit.MINUTES); //5分钟过期

        //  发送给rabbitMQ
        Map<String,String> map = new HashMap<>();
        map.put("phone",phone);
        map.put("code",code);
        amqpTemplate.convertAndSend("","queue.sms", JSON.toJSONString(map));
        return Result.ok();
    }

    @Override
    public void save(TbUser user, String smsCode) {
        //校验
        String sysCode = (String) redisTemplate.boundValueOps("code_" + user.getPhone()).get(); //提取系统的验证码
        if(sysCode==null)
            throw new RuntimeException("验证码未发送或已过期");
        if(!sysCode.equals(smsCode))
            throw new RuntimeException("验证码不正确");
        if(user.getUsername()==null)
            user.setUsername(user.getPhone()); //把手机号作为用户名

        //校验用户名是否已经注册
        QueryWrapper<TbUser> searchUser = new QueryWrapper<>();
        searchUser.eq("username",user.getUsername());
        if(baseMapper.selectCount(searchUser)>0)
            throw new RuntimeException("该手机号已注册");

        //数据添加
        user.setCreated(new Date()); //用户创建时间
        user.setUpdated(new Date()); //修改时间
        user.setPoints(0);  //积分
        user.setStatus("1"); //状态
        user.setIsEmailCheck("0"); //邮箱验证
        user.setIsMobileCheck("1"); //手机验证
        System.out.println(user);
        baseMapper.insert(user);
    }

    /**
     * 登录功能的实现
     * @param user
     * @return
     */
    @Override
    public String login(TbUser user) {
        // 获取登录手机和密码
        String mobile = user.getPhone();
        String password = user.getPassword();

        // 手机号和密码非空判断
        if (StringUtils.isEmpty(mobile) || StringUtils.isEmpty(password)) {
            throw new RuntimeException("登录失败");
        }

        // 判断手机号是否正确
        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", mobile);
        List<TbUser> users = baseMapper.selectList(wrapper);
        if(users.size()==0) {
            throw new RuntimeException("登录失败");
        }

        // 登录成功的用户
        TbUser member = users.get(0);

        // 判断密码
        // 因为存储到数据库密码是加密的
        // 把输入的密码进行加密，再和数据库密码进行比较
        // 加密方式MD5
        if(!MD5.encrypt(password).equals(member.getPassword()))
            throw new RuntimeException("登录失败");


        // 登录成功
        // 生成token字符串，使用jwt工具类
        String jwtToken = JwtUtils.getJwtToken(member.getUsername(), member.getNickName());
        return jwtToken;

    }

    @Transactional(readOnly=true)
    @Override
    public Result selByCount(Map<String, Object> map, Integer page, Integer size) {
        PageHelper.startPage(page,size);
        if(map.get("nickName")!=null && !"".equals(map.get("nickName"))){
            map.replace("nickName","%"+map.get("nickName")+"%");
        }
        List<NewUser> newUsers = tbUserMapper.selByCount(map);
        PageInfo<NewUser> pageInfo=new PageInfo<>(newUsers);
        return Result.ok().data("row",pageInfo.getList()).data("total",pageInfo.getTotal());
    }

    // 根据查询条件封装模块对象
    private QueryWrapper<TbUser> createExample(Map<String, Object> searchMap) {
        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
        if(searchMap!=null) {
            if(searchMap.get("status")!=null)
                wrapper.eq("status",searchMap.get("status"));
            if(searchMap.get("username")!=null && !"".equals(searchMap.get("username")))
                wrapper.like("username",searchMap.get("username"));
            if(searchMap.get("phone")!=null && !"".equals(searchMap.get("phone")))
                wrapper.like("phone",searchMap.get("phone"));
            if(searchMap.get("email")!=null && !"".equals(searchMap.get("email")))
                wrapper.like("email",searchMap.get("email"));
            if(searchMap.get("nickName")!=null && !"".equals(searchMap.get("nickName")))
                wrapper.like("nickName",searchMap.get("nickName"));
        }
        return wrapper;
    }
}
